package com.example.common.generator.entity;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.example.common.config.DbConfig;
import com.example.common.config.GenerConfig;

import java.util.ArrayList;
import java.util.List;

/**
 * 生成配置文件
 */
public class GeneratorConfig {


    /**
     * 数据源
     */
    private DbConfig dataSource;

    /**
     * 配置文件
     */
    private GenerConfig generConfig;


    public GeneratorConfig initConfig(GenerConfig generConfig, DbConfig dataSource) {
        this.generConfig = generConfig;
        this.dataSource = dataSource;
        return this;
    }

    /**
     * 全局配置
     */
    public GlobalConfig initGlobalConfig() {
        GlobalConfig globalConfig = new GlobalConfig();
        // 是否支持AR模式
        globalConfig.setActiveRecord(true);
        // 作者
        globalConfig.setAuthor(generConfig.getAuthor());
        // 生成路径
        globalConfig.setOutputDir(generConfig.getOutTempPath());
        // 文件覆盖
        globalConfig.setFileOverride(true);
        // 主键策略
        globalConfig.setIdType(IdType.AUTO);
        // 是否开启二级缓存
        globalConfig.setEnableCache(false);
        // 设置生成的service接口的名字的首字母是否为I
        globalConfig.setServiceName("I%sService");
        // ResultMap
        globalConfig.setBaseResultMap(true);
        // 字段集合
        globalConfig.setBaseColumnList(true);
        // 时间类型采用Date
        globalConfig.setDateType(DateType.ONLY_DATE);
        // 是否打开文件夹
        globalConfig.setOpen(false);
        //是否启用swagger
        globalConfig.setSwagger2(generConfig.getCreateSwagger());
        return globalConfig;
    }

    /**
     * 数据源配置
     */
    public DataSourceConfig initDataSourceConfig() {
        // 获取数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDriverName(dataSource.getDriverClassName());
        dataSourceConfig.setUrl(dataSource.getUrl());
        dataSourceConfig.setUsername(dataSource.getUserName());
        dataSourceConfig.setPassword(dataSource.getPassword());
        // TODO 其他常用数据库正在开发中，1.0.0只支持MYSQL
        if (dataSource.getDriverClassName().startsWith(DbType.ORACLE.getDb())) {
            dataSourceConfig.setDbType(DbType.ORACLE);
        }
        if (dataSource.getDriverClassName().startsWith(DbType.MYSQL.getDb())) {
            dataSourceConfig.setDbType(DbType.MYSQL);
        }
        if (dataSource.getDriverClassName().startsWith(DbType.SQL_SERVER.getDb())) {
            dataSourceConfig.setDbType(DbType.SQL_SERVER);
        }
        return dataSourceConfig;
    }

    /**
     * 策略配置
     */
    public StrategyConfig initStrategyConfig(String... tableNames) {
        StrategyConfig strategyConfig = new StrategyConfig();
        // 驼峰转连字符
        strategyConfig.setControllerMappingHyphenStyle(true);
        // 数据库表映射到实体的命名策略
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        // Lombok
        strategyConfig.setEntityLombokModel(false);
        // 是否生成实体时，生成字段注解
        strategyConfig.entityTableFieldAnnotationEnable(true);
        // 表前缀
        String[] tablePrefixs = generConfig.getTablePrefix().split(",");

        strategyConfig.setTablePrefix(tablePrefixs);
        // 表名
        strategyConfig.setInclude(tableNames);

        strategyConfig.setRestControllerStyle(true);
        // 公共字段填充
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(new TableFill("CREATE_TIME", FieldFill.INSERT));
        tableFills.add(new TableFill("CREATE_BY", FieldFill.INSERT));
        tableFills.add(new TableFill("UPDATE_TIME", FieldFill.UPDATE));
        tableFills.add(new TableFill("UPDATE_BY", FieldFill.UPDATE));
        strategyConfig.setTableFillList(tableFills);
        return strategyConfig;
    }

    /**
     * 包配置
     */
    public PackageConfig initPackageConfig(String packageName, String moduleName) {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent(packageName);
        packageConfig.setMapper("mapper");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setController("controller");
        packageConfig.setEntity("entity");
        packageConfig.setModuleName(moduleName);
//        packageConfig.setXml("mapper.xml");
        return packageConfig;
    }

    /**
     * 模板配置
     */
    public TemplateConfig initTemplateConfig() {
        TemplateConfig templateConfig = new TemplateConfig();
        String prefix = "/templates/ftl/plus";
        if (generConfig.getTempType().equals("vm")) {
            prefix = "/templates/vm/plus";
        }
        templateConfig.setController(prefix + "/controller.java");
        templateConfig.setEntity(prefix + "/entity.java");
        templateConfig.setService(prefix + "/service.java");
        templateConfig.setServiceImpl(prefix + "/serviceImpl.java");
        templateConfig.setMapper(prefix + "/mapper.java");
        templateConfig.setXml(null);
        return templateConfig;
    }

    public InjectionConfig initInjectionConfig(String moduleName) {
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        String templatePath = "/templates/ftl/plus/mapper.xml.ftl";
        if (generConfig.getTempType().equals("vm")) {
            templatePath = "/templates/vm/plus/mapper.xml.vm";
        }
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {

                return generConfig.getOutTempPath() + "/resources/mybatis/" + moduleName + "/" + tableInfo.getEntityName() + ".xml";
            }
        });
        cfg.setFileOutConfigList(focList);
        return cfg;
    }


    /**
     * 模板引擎
     */
    public FastCodingTemplateEngine initTemplateEngine() {
        FastCodingTemplateEngine templateEngine = new FastCodingTemplateEngine();
        return templateEngine;
    }


}
